/**
 * 
 * Proj. Wireless - UFRN
 * JFrameTest
 */
package gui;

import API_Jung.MyMouseMenus;
import API_Jung.PopupVertexEdgeMenuMousePlugin;
import API_itextpdf.ManagerPDF;
import com.itextpdf.text.DocumentException;
import edu.uci.ics.jung.algorithms.layout.KKLayout;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.visualization.FourPassImageShaper;
import edu.uci.ics.jung.visualization.LayeredIcon;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.EditingModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.EllipseVertexShapeTransformer;
import edu.uci.ics.jung.visualization.decorators.VertexIconShapeTransformer;
import edu.uci.ics.jung.visualization.renderers.DefaultEdgeLabelRenderer;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import metodologia.*;
import org.apache.commons.collections15.Factory;
import org.apache.commons.collections15.Transformer;

/**
 * Frame principal do PW-Execute
 * 
 * @author PW-UFRN
 */
public class JFTest extends javax.swing.JFrame {

    /** Armazena o titulo da janela */
    private String title;
    
    /** Objeto que armazena a metodologia */
    private Metodologia metodologia;
    /** Objeto que armazena DadosMetodologia */
    private DadosMetodologia dadosMetodologia;
    /** Objeto do DadosMetodologia para serializar */
    private SerializarObjetoCryptografado<DadosMetodologia> object;
    /** Objeto do Progress para serializar */
    private SerializarObjetoCryptografado<FileProgress> object_progress;
    /** Objeto que armazena o progresso */
    private ArrayList<Progress> progress;
    /** Objeto que armazena o progresso em uma classe serializavel */
    private FileProgress fileProgress;
    
    private String dataMD5;
    
    private int nodetype, nTests, nEdges, nVertex;
    private int nVertex2, nEdges2;
    private DirectedSparseGraph<TestNode, String> g; //Grafo da tela principal
    private DirectedSparseGraph<TestNode, String> g1; //Grafo da subtela - Conjunto de etapas
    private DirectedSparseGraph<ToDoNode, String> g2;
    private TestNode start, end;
    
    /** Objetos para visualizar */
    private VisualizationViewer<TestNode, String> vv;
    private KKLayout<TestNode, String> layout;
    private JScrollPane graphScroll;
    private EditingModalGraphMouse<TestNode, String> graphMouse;
    
    /** Frame de Versão */
    private JFMetodology frameVersion;
    
    /** Frame Sobre */
    private JFAbout frameSobre;
    
    /** Armazena todas as listas possiveis */
    private ArrayList<Aresta> listEdgeTest;
    private ArrayList<Aresta> listEdgeStep;
    private ArrayList<TestNode> listVertexTests;
    private ArrayList<ToDoNode> listVertexSteps;
    
    private double xMin, yMin, xMax, yMax, deslocamentoX, deslocamentoY;
    private int dx, dy;
    // deslocamentoHorizontal é verdadeiro se for para direita
    // deslocamentovertical é verdadeiro se for para cima
    private boolean primeiraVez, deslocamentoHorizontal, deslocamentoVertical;

    /** Creates new form MetodologiadeTestes */
    public JFTest() throws Exception {
        
        //Titulo da Tela
        this.title = "PW-Execute";
        setTitle(title);
        //Coloca icone do logo do projeto
        ImageIcon imagemTituloJanela = new ImageIcon(getClass().getResource("/ImageFiles/icon_PW.png"));  
        setIconImage(imagemTituloJanela.getImage());
        //Tamanho minimo
        this.setMinimumSize(new Dimension(750,450));
        
        initComponents();
        
        //Coloca icone do logo na tela de apresentação
        Icon icon = new LayeredIcon(new ImageIcon(getClass().getResource("/ImageFiles/Logo.png")).getImage());
        logo.setIcon(icon);
        
        createToolBar();
        
        //Inicialização de variáveis
        this.dadosMetodologia = new DadosMetodologia();
        this.fileProgress = new FileProgress();
        
        dataMD5 = "";
        
        nVertex = 0;
        nVertex2 = 0;
        nTests = 1;
        nEdges = 1;
        nEdges2 = 1;
        
        object = new SerializarObjetoCryptografado<>();
        object_progress = new SerializarObjetoCryptografado<>();
        
        listEdgeTest = new ArrayList<>();
        listEdgeStep = new ArrayList<>();
        listVertexTests = new ArrayList<>();
        listVertexSteps = new ArrayList<>();
        
        fileChooser.setDialogTitle("[Arquivo de Metodologia]");
        fileChooser2.setDialogTitle("[Arquivo de Progresso]");
        fileChooser3.setDialogTitle("");

        fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter(){
            //Filtro, converte as letras em minúsculas antes de comparar
            @Override
            public boolean accept(File f){
                return f.getName().toLowerCase().endsWith(".met") || f.isDirectory();
            }
            //Texto que será exibido para o usuário
            @Override
            public String getDescription() {
                return "Arquivos de metodologia (.met)";
            }
        });
        fileChooser2.setFileFilter(new javax.swing.filechooser.FileFilter(){
            //Filtro, converte as letras em minúsculas antes de comparar
            @Override
            public boolean accept(File f){
                return f.getName().toLowerCase().endsWith(".pgr") || f.isDirectory();
            }
            //Texto que será exibido para o usuário
            @Override
            public String getDescription() {
                return "Arquivos de progresso (.pgr)";
            }
        });
        fileChooser3.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        
        configAction(); //Realiza as configurações de ações do usuario na aplicação
        this.setLocationRelativeTo(null);

}

    /**
     * Metodo de configuração da tela
     */
    private void configAction(){
        
        addWindowListener(new WindowAdapter() {
                
            @Override
            public void windowClosing (WindowEvent e) {
            
                int response;
            
                if (b_open2.isVisible()){

                    response = JOptionPane.showConfirmDialog(null, "Deseja salvar o progresso da execução?", "Aviso", JOptionPane.YES_NO_OPTION);
                    if (response == JOptionPane.YES_OPTION){
                        Save2ActionPerformed();
                    }
                    
                    response = JOptionPane.showConfirmDialog(null, "Deseja sair do programa?");
                    if (response == JOptionPane.YES_OPTION){
                        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
                    } else{
                        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
                    }
                }
                
            }
        });
    }

    /**
     * Constroi a barra de ferramentas
     */
    private void createToolBar() {
        
        this.b_Save2.setToolTipText("Salvar Progresso");
        this.b_Open.setToolTipText("Abrir Metodologia");
        this.b_open2.setToolTipText("Abrir Progresso");
        this.b_report.setToolTipText("Gerar Relatório");
       
        b_open2.setVisible(false);
        b_Save2.setVisible(false);
        b_report.setVisible(false);
        
        aboutMetodology.setVisible(false);
        
    }

    /**
     * Constrói a tela inicial sem dados dos vertices
     */
    public final void createGraphScreen() {
        
        JTabbedPane GraphS = new JTabbedPane();
        
        g1 = new DirectedSparseGraph<>();
        
        layout = new KKLayout(g1);
        layout.setSize(new Dimension(300, 300));

        vv = new VisualizationViewer<>(layout);
        vv.setPreferredSize(new Dimension(300, 300));
        vv.setBackground(Color.WHITE);

        //Setando as descrições dos vertices
        vv.getRenderContext().setVertexLabelTransformer(new Transformer<TestNode, String>() {
            @Override
            public String transform(TestNode v) {
                switch (v.getType()) {
                    case 0:
                        return "";
                    case 1:
                        return "";
                    case 2:
                        return "\bDescrição: \n" + v.getJFData().getDescricao();
                }
                return "Erro";
            }
        });
        
        //Setando as descrições das arestas
        vv.getRenderContext().setEdgeLabelTransformer(new Transformer<String, String>() {

            @Override
            public String transform(String e) {
                return "";
            }
        });

        vv.getRenderContext().setVertexIconTransformer(      
                new MyVertexIconTransformer<TestNode>());
        
        vv.getRenderContext().setVertexShapeTransformer(
                new MyVertexIconShapeTransformer<>(new EllipseVertexShapeTransformer<TestNode>()));
        
        vv.getRenderContext().setEdgeLabelRenderer(new DefaultEdgeLabelRenderer(Color.cyan));
        
        vv.setVertexToolTipTransformer(vv.getRenderContext().getVertexLabelTransformer());

        Factory<TestNode> vertexFactory = new VertexFactory();
        Factory<String> edgeFactory = new EdgeFactory();

        graphMouse = new EditingModalGraphMouse<>(vv.getRenderContext(), vertexFactory, edgeFactory);

        PopupVertexEdgeMenuMousePlugin myPlugin = new PopupVertexEdgeMenuMousePlugin();
        
        JPopupMenu vertexMenu = new MyMouseMenus.VertexMenu();
        JPopupMenu EdgeMenu = new MyMouseMenus.EdgeMenu();

        myPlugin.setVertexPopup(vertexMenu);
        myPlugin.setEdgePopup(EdgeMenu);
        
        graphMouse.remove(graphMouse.getPopupEditingPlugin());  // Removes the existing popup editing plugin

        graphMouse.add(myPlugin);   // Add our new plugin to the mouse

        vv.setGraphMouse(graphMouse);
        
        vv.addKeyListener(graphMouse.getModeKeyListener());

        graphMouse.setMode(ModalGraphMouse.Mode.TRANSFORMING);

        graphScroll = new JScrollPane(vv);
        graphScroll.setSize(this.GraphScreen.getSize());

        GraphS.addTab("Testes", graphScroll);

        GraphScreen.setLayout(new BorderLayout());
        GraphScreen.add("Center", GraphS);
        
        if (!dadosMetodologia.getListaDeTestes().isEmpty()) {
            logo.setVisible(false);
            reloadGraphScreen();
        } else {
            vv.setVisible(false);
            logo.setVisible(true);
        }
    }
    
    /**
     * Reconstrói a tela com os dados de "dadosMetodologia"
     */
    public final void reloadGraphScreen() {
        
        g1 = null;
        g1 = new DirectedSparseGraph<>();
        
        Teste test_aux; //Recebe os componentes da lista
        TestNode testNode;
        
        //
        //Criação do grafo a partir da lista de arestas recebidas
        //
        for(Iterator i = dadosMetodologia.getListaDeTestes().iterator(); i.hasNext();){
            test_aux = (Teste)i.next();

            if(primeiraVez){
                xMin = test_aux.getX(); yMin = test_aux.getY();
                primeiraVez = false;
            }

            verificarTamanho(test_aux.getX(), test_aux.getY());

            // Falta colocar os outros dados do TestNode
            testNode = new TestNode(test_aux.getId(), test_aux.getType(), test_aux.getCatid());
            testNode.setX(test_aux.getX());
            testNode.setY(test_aux.getY());
            testNode.setNome(test_aux.getTitulo());
            testNode.setDescricao(test_aux.getDescricaoTeste());
            testNode.getJFData().setNome(test_aux.getTitulo());
            testNode.getJFData().setDescricao(test_aux.getDescricaoTeste());
            testNode.getToDoScreen().setNovo(false);
            testNode.setG(processToDoNode(test_aux));
            testNode.getToDoScreen().setG(testNode.getG());
            testNode.getToDoScreen().reloadGraphScreen();

            //Enviando para todos os testes do grafo da janela principal
            testNode.getToDoScreen().setG_pai(g1);
            g1.addVertex(testNode);
            listVertexTests.add(testNode);
            if (test_aux.getType() == 0) start = testNode;
            else if (test_aux.getType() == 1) end = testNode;

        }

        definirParametrosDeDeslocamento();
        // Definir Tamanho da tela
        this.setSize(dx + 120, dy + 220);

        Aresta aresta;

        for(Iterator i = dadosMetodologia.getListaDasArestasDosTestes().iterator(); i.hasNext();){
            aresta = (Aresta) i.next();
            if (aresta.getIdOrigem() != aresta.getIdDestino()){ // so adiciona aresta se n for loop
                g1.addEdge(aresta.getEdge(), processTestNode(aresta.getIdOrigem()), processTestNode(aresta.getIdDestino()));
                listEdgeTest.add(aresta);
            }
        }
            
        //
        //Setanado o grafo no layout
        //
        layout.setGraph(g1);
        
        // Setando localização de Nós
        for (Iterator it = g1.getVertices().iterator(); it.hasNext();) {
            TestNode object_aux = (TestNode) it.next();
            
            if(deslocamentoHorizontal){ // Direita
                object_aux.setX(object_aux.getX() + deslocamentoX);
            }else{ // Esquerda
                object_aux.setX(object_aux.getX() - deslocamentoX);
            }
            
            if(deslocamentoVertical){ // Cima
                object_aux.setY(object_aux.getY() + deslocamentoY);
            }else{ // Baixo
                object_aux.setY(object_aux.getY() - deslocamentoY);
            }            
            
            layout.setLocation(object_aux, new Point2D.Double(object_aux.getX(), object_aux.getY()));
            if (object_aux.getType() == 2) {
                nTests++;
            }
        }
        
        //
        //Setando o layout no visualization view
        //
        
        //Setando os nomes dos vertices
        vv.getRenderContext().setVertexLabelTransformer(new Transformer<TestNode, String>() {
            @Override
            public String transform(TestNode v) {
                switch (v.getType()) {
                    case 0:
                        return "Inicio";
                    case 1:
                        return "Final";
                    case 2:
                        return v.getJFData().getNome();
                }
                return "Erro";
            }
        });
        
        //Setando as descrições das arestas
        vv.getRenderContext().setEdgeLabelTransformer(new Transformer<String, String>() {

            @Override
            public String transform(String i) {
                return "";
            }
        });
        
        vv.setGraphLayout(layout);
        
        vv.getRenderContext().setVertexIconTransformer(
                new MyVertexIconTransformer<TestNode>());
        
        vv.getRenderContext().setEdgeLabelRenderer(new DefaultEdgeLabelRenderer(Color.cyan));
        
        Factory<TestNode> vertexFactory = new JFTest.VertexFactory();
        Factory<String> edgeFactory = new JFTest.EdgeFactory();
        
        graphMouse = new EditingModalGraphMouse<>(vv.getRenderContext(), vertexFactory, edgeFactory);

        //
        //Adicionando alguns "popup menus" para os vertices e arestas para o "mouse plugin"
        //
        
        PopupVertexEdgeMenuMousePlugin myPlugin = new PopupVertexEdgeMenuMousePlugin();
        
        JPopupMenu vertexMenu = new MyMouseMenus.VertexMenu();
        JPopupMenu EdgeMenu = new MyMouseMenus.EdgeMenu();

        myPlugin.setVertexPopup(vertexMenu);
        myPlugin.setEdgePopup(EdgeMenu);
        
        graphMouse.remove(graphMouse.getPopupEditingPlugin());

        graphMouse.add(myPlugin);

        //
        //Setando plugins do mouse
        //
        vv.setGraphMouse(graphMouse);
        vv.addKeyListener(graphMouse.getModeKeyListener());

        //
        //Setando o modo do mouse na tela. "TRANSFORMING" transforme apenas modifica o lugar do grafo como um todo.
        //
        graphMouse.setMode(ModalGraphMouse.Mode.TRANSFORMING);
        
        nEdges = g1.getEdgeCount();
        nVertex = g1.getVertexCount();

        //
        //Setando o visualization view no graphScroll(ScrollBar)
        //
        this.graphScroll.setViewportView(vv);
        
        //Colocando o titulo
        setTitle(dadosMetodologia.getNome() + " - " + title);
        
        //Ao carregar uma met, redimensiona o tamanho da tela para que a met fique toda na tela
        
    }
    
        private void verificarTamanho(double x, double y) {
        xMin = Math.min(xMin, x); xMax = Math.max(xMax, x);
        yMin = Math.min(yMin, y); yMax = Math.max(yMax, y);
//        System.out.println("Teste: " + titulo + " x = " + x + " xMin = "
//                + xMin + "xMax = " + xMax + " y = " + y + " yMin = " +
//                yMin + " yMax = " + yMax);
    }
    
    private void definirParametrosDeDeslocamento() {
        dx = Math.round((float)(xMax - xMin));
        dy = Math.round((float)(yMax - yMin));
        
        int posicaoInicialX = 40, posicaoInicialY = 40;
        
        if(xMin < posicaoInicialX){
            deslocamentoX = posicaoInicialX - xMin;
            deslocamentoHorizontal = true; // Direita
        }else{
            deslocamentoX = xMin - posicaoInicialX;
            deslocamentoHorizontal = false; // Esquerda
        }
        
        if(yMin < posicaoInicialY){
            deslocamentoY = posicaoInicialY - yMin;
            deslocamentoVertical = true; // cima
        }else{
            deslocamentoY = yMin - posicaoInicialY;
            deslocamentoVertical = false; // Cima
        }
    }
    
    /**
     * Implementa o metodo "transform" do grafo.
     * @param <TestNode> 
     */
    public class MyVertexIconTransformer<TestNode> implements
            Transformer<TestNode, Icon> {

        @Override
        public Icon transform(TestNode n) {
            String[] n2 = n.toString().split("nici");
            String[] n3 = n.toString().split("ina");
            Icon icone;
                
            if (n2.length > 1) {
                icone = new LayeredIcon(new ImageIcon(getClass().getResource("/ImageFiles/StartBall.png")).getImage());
                start.setState(3);
                return icone;
            } else if (n3.length > 1) {
                icone = new LayeredIcon(new ImageIcon(getClass().getResource("/ImageFiles/EndNode.png")).getImage());
                return icone;
            } else {                
                // Função que implementa o lógica de mudança de cores.
                defineState(g1, n.toString());
                
                //atualiza automaticamente a cor de todos os nos.
                vv.repaint();
                
                // Invoca a função "readIcon" que define o icone a partir do estado do nó.
                icone = new LayeredIcon(new ImageIcon(getClass().getResource(readIcon(g1, n.toString()))).getImage());
                return icone;
            }
        }
    }

    public static class MyVertexIconShapeTransformer<TestNode> extends VertexIconShapeTransformer<TestNode> {

        boolean shapeImages = true;

        public MyVertexIconShapeTransformer(Transformer<TestNode, Shape> delegate) {
            super(delegate);
        }

        /**
         * @return Returns the shapeImages.
         */
        public boolean isShapeImages() {
            return shapeImages;
        }

        /**
         * @param shapeImages The shapeImages to set.
         */
        public void setShapeImages(boolean shapeImages) {
            shapeMap.clear();
            this.shapeImages = shapeImages;
        }

        public Icon getIcon(TestNode n) {
            String[] n2 = n.toString().split("nici");
            String[] n3 = n.toString().split("ina");
            if (n2.length > 1) {
                Icon icon = new LayeredIcon(new ImageIcon(getClass().getResource("/ImageFiles/StartBall.png")).getImage());
                return icon;
            } else if (n3.length > 1) {
                Icon icon = new LayeredIcon(new ImageIcon(getClass().getResource("/ImageFiles/EndNode.png")).getImage());
                return icon;
            } else {
                Icon icon = new LayeredIcon(new ImageIcon(getClass().getResource("/ImageFiles/TestNode.png")).getImage());
                return icon;
            }
        }

        @Override
        public Shape transform(TestNode v) {
            Icon icon = getIcon(v);

            if (icon != null && icon instanceof ImageIcon) {

                Image image = ((ImageIcon) icon).getImage();

                Shape shape = shapeMap.get(image);
                if (shape == null) {
                    if (shapeImages) {
                        shape = FourPassImageShaper.getShape(image, 30);
                    } else {
                        shape = new Rectangle2D.Float(0, 0,
                                image.getWidth(null), image.getHeight(null));
                    }
                    if (shape.getBounds().getWidth() > 0
                            && shape.getBounds().getHeight() > 0) {
                        int width = image.getWidth(null);
                        int height = image.getHeight(null);
                        AffineTransform transform =
                                AffineTransform.getTranslateInstance(-width / 2, -height / 2);
                        shape = transform.createTransformedShape(shape);
                        shapeMap.put(image, shape);
                    }
                }
                return shape;
            } else {
                return delegate.transform(v);
            }
        }
    }

    /**
     * Implementa a construção de vertices
     */
    private class VertexFactory implements Factory<TestNode> {

        @Override
        public TestNode create() {
            nodetype = 2;
            switch (nodetype) {
                case 0:
                    start = new TestNode(nVertex++, nodetype, 0);
                    return start;
                case 1:
                    end = new TestNode(nVertex++, nodetype, 0);
                    return end;
                case 2:
                    return (new TestNode(nVertex++, nodetype, nTests++));
            }
            return new TestNode(0, 0, 0);
        }
    }

    /**
     * Implementa a construção de arestas
     */
    private class EdgeFactory implements Factory<String> {

        @Override
        public String create() {
            return ("" + nEdges++);
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        fileChooser = new javax.swing.JFileChooser();
        fileChooser2 = new javax.swing.JFileChooser();
        fileChooser3 = new javax.swing.JFileChooser();
        jToolBar1 = new javax.swing.JToolBar();
        b_Open = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        b_open2 = new javax.swing.JButton();
        b_Save2 = new javax.swing.JButton();
        b_report = new javax.swing.JButton();
        GraphScreen = new javax.swing.JPanel();
        logo = new javax.swing.JLabel();
        jMenuBar1 = new javax.swing.JMenuBar();
        data_menu = new javax.swing.JMenu();
        openMet_submenu = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        openProg_submenu = new javax.swing.JMenuItem();
        saveProg_submenu = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        gerarrRelat_submenu = new javax.swing.JMenuItem();
        jSeparator4 = new javax.swing.JPopupMenu.Separator();
        close_submenu = new javax.swing.JMenuItem();
        ajuda_menu = new javax.swing.JMenu();
        aboutMetodology = new javax.swing.JMenuItem();
        aboutSoftware = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jToolBar1.setFloatable(false);

        b_Open.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/12.png"))); // NOI18N
        b_Open.setFocusable(false);
        b_Open.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        b_Open.setMaximumSize(new java.awt.Dimension(29, 29));
        b_Open.setMinimumSize(new java.awt.Dimension(29, 29));
        b_Open.setPreferredSize(new java.awt.Dimension(29, 29));
        b_Open.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        b_Open.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                b_OpenActionPerformed(evt);
            }
        });
        jToolBar1.add(b_Open);
        jToolBar1.add(jSeparator1);

        b_open2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/13.png"))); // NOI18N
        b_open2.setFocusable(false);
        b_open2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        b_open2.setMaximumSize(new java.awt.Dimension(29, 29));
        b_open2.setMinimumSize(new java.awt.Dimension(29, 29));
        b_open2.setPreferredSize(new java.awt.Dimension(29, 29));
        b_open2.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        b_open2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                b_open2ActionPerformed(evt);
            }
        });
        jToolBar1.add(b_open2);

        b_Save2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/29.png"))); // NOI18N
        b_Save2.setFocusable(false);
        b_Save2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        b_Save2.setMaximumSize(new java.awt.Dimension(29, 29));
        b_Save2.setMinimumSize(new java.awt.Dimension(29, 29));
        b_Save2.setPreferredSize(new java.awt.Dimension(29, 29));
        b_Save2.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        b_Save2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                b_Save2ActionPerformed(evt);
            }
        });
        jToolBar1.add(b_Save2);

        b_report.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/18.png"))); // NOI18N
        b_report.setFocusable(false);
        b_report.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        b_report.setMaximumSize(new java.awt.Dimension(29, 29));
        b_report.setMinimumSize(new java.awt.Dimension(29, 29));
        b_report.setPreferredSize(new java.awt.Dimension(29, 29));
        b_report.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        b_report.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                b_reportActionPerformed(evt);
            }
        });
        jToolBar1.add(b_report);

        getContentPane().add(jToolBar1, java.awt.BorderLayout.NORTH);

        GraphScreen.add(logo);

        getContentPane().add(GraphScreen, java.awt.BorderLayout.CENTER);

        data_menu.setText("Arquivo");

        openMet_submenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        openMet_submenu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/12.png"))); // NOI18N
        openMet_submenu.setText("Carregar Metodologia");
        openMet_submenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openMet_submenuActionPerformed(evt);
            }
        });
        data_menu.add(openMet_submenu);
        data_menu.add(jSeparator2);

        openProg_submenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P, java.awt.event.InputEvent.CTRL_MASK));
        openProg_submenu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/13.png"))); // NOI18N
        openProg_submenu.setText("Carregar Progresso");
        openProg_submenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openProg_submenuActionPerformed(evt);
            }
        });
        data_menu.add(openProg_submenu);

        saveProg_submenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        saveProg_submenu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/29.png"))); // NOI18N
        saveProg_submenu.setText("Salvar Progresso");
        saveProg_submenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveProg_submenuActionPerformed(evt);
            }
        });
        data_menu.add(saveProg_submenu);
        data_menu.add(jSeparator3);

        gerarrRelat_submenu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/18.png"))); // NOI18N
        gerarrRelat_submenu.setText("Gerar Relatório");
        gerarrRelat_submenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                gerarrRelat_submenuActionPerformed(evt);
            }
        });
        data_menu.add(gerarrRelat_submenu);
        data_menu.add(jSeparator4);

        close_submenu.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_MASK));
        close_submenu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/26.png"))); // NOI18N
        close_submenu.setText("Sair");
        close_submenu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                close_submenuActionPerformed(evt);
            }
        });
        data_menu.add(close_submenu);

        jMenuBar1.add(data_menu);

        ajuda_menu.setText("Ajuda");
        ajuda_menu.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                ajuda_menuMouseClicked(evt);
            }
        });

        aboutMetodology.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/34-30x30.png"))); // NOI18N
        aboutMetodology.setText("Sobre a Metodologia");
        aboutMetodology.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                aboutMetodologyActionPerformed(evt);
            }
        });
        ajuda_menu.add(aboutMetodology);

        aboutSoftware.setIcon(new javax.swing.ImageIcon(getClass().getResource("/ImageFiles/icon_PW2.png"))); // NOI18N
        aboutSoftware.setText("Sobre o PW-Execute");
        aboutSoftware.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                aboutSoftwareActionPerformed(evt);
            }
        });
        ajuda_menu.add(aboutSoftware);

        jMenuBar1.add(ajuda_menu);

        setJMenuBar(jMenuBar1);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void b_OpenActionPerformed(java.awt.event.ActionEvent evt) {                                       


		fileChooser.setDialogTitle("Abrir " + "[Arquivo de Metodologia]");

		if (vv == null){

			int returnVal = fileChooser.showOpenDialog(this);
			String diretorio = "";

			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File file = fileChooser.getSelectedFile();
				diretorio = file.getAbsolutePath();
				dadosMetodologia = object.deserializar(diretorio);
                                
//                                if ((!dadosMetodologia.getListaDeTestes().isEmpty()) && (!dadosMetodologia.getListaDasArestasDosTestes().isEmpty())){
//                                
                                    try{
                                        dataMD5 = object.generatorMD5(diretorio);
                                    } catch (NoSuchAlgorithmException ex) {
                                        System.out.println("[Erro] " + ex.toString());
                                    } catch (IOException ex){
                                        System.out.println("[Erro] " + ex.toString());
                                    }

                                    System.out.println("** Carregou dadosMetodologia com sucesso! **");
                                    JOptionPane.showMessageDialog(null, "Carregou Metodologia com sucesso! \n Aguarde um momento enquanto a metodologia está abrindo.", "Aviso", JOptionPane.INFORMATION_MESSAGE);

                                    createGraphScreen();

                                    b_open2.setVisible(true);
                                    b_Save2.setVisible(true);
                                    b_report.setVisible(true);
                                    
                                    aboutMetodology.setVisible(true);
//                                } else {
//                                    
//                                    String aux_message = "Metodologia Indisponível! \nConsulte o criador e verifique como a metodologia está organizada.";
//                                    JOptionPane.showMessageDialog(null, aux_message, "Aviso", JOptionPane.WARNING_MESSAGE);
//                                }
			}

		} else {

			int response;

			response = JOptionPane.showConfirmDialog(null, "Deseja salvar o progresso da execução?", "Aviso", JOptionPane.YES_NO_OPTION);
			if (response == JOptionPane.YES_OPTION){
				b_Save2ActionPerformed(evt);
			}

			int returnVal = fileChooser.showOpenDialog(this);
			String diretorio = "";

			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File file = fileChooser.getSelectedFile();
				diretorio = file.getAbsolutePath();
				dadosMetodologia = object.deserializar(diretorio);
                                
                                if ((!dadosMetodologia.getListaDeTestes().isEmpty()) && (!dadosMetodologia.getListaDasArestasDosTestes().isEmpty())){
                                
                                    try{
                                        dataMD5 = object.generatorMD5(diretorio);
                                    } catch (NoSuchAlgorithmException ex) {
                                        System.out.println("[Erro] " + ex.toString());
                                    } catch (IOException ex){
                                        System.out.println("[Erro] " + ex.toString());
                                    }

                                    System.out.println("** Carregou dadosMetodologia com sucesso! **");
                                    JOptionPane.showMessageDialog(null, "Carregou Metodologia com sucesso!", "Aviso", JOptionPane.INFORMATION_MESSAGE);

                                    GraphScreen.setVisible(false);
                                    //Fecha todas as janelas internas
                                    for (Iterator it = g1.getEdges().iterator(); it.hasNext();) {
                                            String edge = (String) it.next();
                                            g1.getEndpoints(edge).getSecond().getToDoScreen().dispose();
                                            g1.getEndpoints(edge).getSecond().getToDoScreen().disposeAll();
                                    }
                                    getContentPane().remove(GraphScreen); //Remove o painel
                                    GraphScreen = new JPanel(); //Cria um novo painel
                                    getContentPane().add(GraphScreen); //Adiciona o novo painel
                                    createGraphScreen();
                                    GraphScreen.setVisible(true);

                                    b_open2.setVisible(true);
                                    b_Save2.setVisible(true);
                                    
                                    aboutMetodology.setVisible(true);
                                
                                } else {
                                    
                                    String aux_message = "Metodologia Indisponível! \nConsulte o criador e verifique como a metodologia está organizada.";
                                    JOptionPane.showMessageDialog(null, aux_message, "Aviso", JOptionPane.WARNING_MESSAGE);
                                }
			}

		}
    }

    private void saveProg_submenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveProg_submenuActionPerformed
     
        Save2ActionPerformed();
    }//GEN-LAST:event_saveProg_submenuActionPerformed

    private void b_open2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_b_open2ActionPerformed

        fileChooser2.setDialogTitle("Abrir [Arquivo de Progresso]");
        
        int returnVal2 = fileChooser2.showOpenDialog(this);
        String diretorio2 = "";

        if (returnVal2 == JFileChooser.APPROVE_OPTION) {
            File file2 = fileChooser2.getSelectedFile();
            diretorio2 = file2.getAbsolutePath();
            try {
                fileProgress = object_progress.deserializar(diretorio2);
                if(fileProgress.getTextMetodology().equals(dataMD5)){
                    dadosMetodologia.setProgress(fileProgress.getProgress());
                    //Carregar o progresso
                    progress = new ArrayList<>();
                    loadProgress();
                    System.out.println("** Carregou Progresso com sucesso! **");
                    JOptionPane.showMessageDialog(null, "Carregou execução/progresso com sucesso!", "Aviso", JOptionPane.INFORMATION_MESSAGE);
                } else{
                    JOptionPane.showMessageDialog(null, "Não foi possível carregar execução/progresso! \n Verifique se o arquivo de execução/progresso é referente ao arquivo de metodologia iniciado.", "Aviso", JOptionPane.ERROR_MESSAGE);
                }
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(null, "Não foi possível carregar execução/progresso! \n Verifique se o arquivo de execução/progresso é referente ao arquivo de metodologia iniciado.", "Aviso", JOptionPane.ERROR_MESSAGE);
            }
        }

    }//GEN-LAST:event_b_open2ActionPerformed

    private void b_Save2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_b_Save2ActionPerformed

        Save2ActionPerformed();
    }//GEN-LAST:event_b_Save2ActionPerformed

    private void openProg_submenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openProg_submenuActionPerformed

        if(b_open2.isVisible()){
            b_open2ActionPerformed(evt);
        } else {
            JOptionPane.showMessageDialog(null, "Nenhuma Metodologia Iniciada!");
        }
    }//GEN-LAST:event_openProg_submenuActionPerformed

    private void openMet_submenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMet_submenuActionPerformed
        // TODO add your handling code here:
        
        b_OpenActionPerformed(evt);
    }//GEN-LAST:event_openMet_submenuActionPerformed

    private void close_submenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_close_submenuActionPerformed
        // TODO add your handling code here:
        
        int response;
        
        response = JOptionPane.showConfirmDialog(null, "Deseja salvar o progresso da execução?", "Aviso", JOptionPane.YES_NO_OPTION);
        if (response == JOptionPane.YES_OPTION){
            b_Save2ActionPerformed(evt);
        }

        if (response != JOptionPane.CANCEL_OPTION){
            response = JOptionPane.showConfirmDialog(null, "Deseja sair do programa?");
            if (response == JOptionPane.YES_OPTION){
                System.exit(0);
            }
        }
        
    }//GEN-LAST:event_close_submenuActionPerformed

    private void gerarrRelat_submenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gerarrRelat_submenuActionPerformed

        if(b_report.isVisible()){
            b_reportActionPerformed(evt);
        } else {
            JOptionPane.showMessageDialog(null, "Nenhuma Metodologia Iniciada!");
        }
        
    }//GEN-LAST:event_gerarrRelat_submenuActionPerformed

    private void ajuda_menuMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_ajuda_menuMouseClicked

 }//GEN-LAST:event_ajuda_menuMouseClicked

    private void aboutMetodologyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutMetodologyActionPerformed

        frameVersion = new JFMetodology(dadosMetodologia);
        frameVersion.setTitle("Sobre a Metodologia");
        frameVersion.setVisible(true);
        
    }//GEN-LAST:event_aboutMetodologyActionPerformed

    private void aboutSoftwareActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutSoftwareActionPerformed

        frameSobre = new JFAbout(dadosMetodologia);
        frameSobre.setTitle("Sobre o " + title);
        frameSobre.setVisible(true);
        
    }//GEN-LAST:event_aboutSoftwareActionPerformed

    private void b_reportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_b_reportActionPerformed
        // TODO add your handling code here:
        
        ManagerPDF pdf = new ManagerPDF();
        DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH-mm-ss");
        Date date = new Date();
        String dataString = dateFormat.format(date);

        fileChooser3.setDialogTitle("Escolha um diretorio para salvar!");

            if(fileChooser3.showSaveDialog(this) == JFileChooser.APPROVE_OPTION){
                
                //Processando o diretorio escolhido
                String[] aux1_diretorio = fileChooser3.getSelectedFile().getAbsolutePath().split("\\\\");
                String aux2_diretorio = "";
                for(int i=0; i<aux1_diretorio.length; i++){
                    if(i != aux1_diretorio.length-1){
                        aux2_diretorio = aux2_diretorio + aux1_diretorio[i] + "/";
                    } else{
                        aux2_diretorio = aux2_diretorio + aux1_diretorio[i];
                    }
                }
                aux2_diretorio = aux2_diretorio + ("/Relatório_" + dadosMetodologia.getNome() + "_" + dataString + ".pdf");

                progress = new ArrayList<>();
                saveProgress();

                ArrayList<String[]> dados = relatorioSimples();
                ArrayList<String[]> dados2 = relatorioSimples2();
                ArrayList<Anexo> dadosAnexo = relatorioAnexo();

                try {
                    pdf.createPdf(this.dadosMetodologia, nTests, dados, dados2, dadosAnexo, aux2_diretorio);
                    JOptionPane.showMessageDialog(null, "Relatório gerado com sucesso! \n Salvo em " + aux2_diretorio + ".", "Aviso", JOptionPane.INFORMATION_MESSAGE);
                    System.out.println("Relatorio salvo: "+ aux2_diretorio);
                } catch (    DocumentException | IOException ex) {
                    Logger.getLogger(JFTest.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        
            
    }//GEN-LAST:event_b_reportActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel GraphScreen;
    private javax.swing.JMenuItem aboutMetodology;
    private javax.swing.JMenuItem aboutSoftware;
    private javax.swing.JMenu ajuda_menu;
    private javax.swing.JButton b_Open;
    private javax.swing.JButton b_Save2;
    private javax.swing.JButton b_open2;
    private javax.swing.JButton b_report;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JMenuItem close_submenu;
    private javax.swing.JMenu data_menu;
    private javax.swing.JFileChooser fileChooser;
    private javax.swing.JFileChooser fileChooser2;
    private javax.swing.JFileChooser fileChooser3;
    private javax.swing.JMenuItem gerarrRelat_submenu;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JPopupMenu.Separator jSeparator3;
    private javax.swing.JPopupMenu.Separator jSeparator4;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JLabel logo;
    private javax.swing.JMenuItem openMet_submenu;
    private javax.swing.JMenuItem openProg_submenu;
    private javax.swing.JMenuItem saveProg_submenu;
    // End of variables declaration//GEN-END:variables
    
    
    private void Save2ActionPerformed(){
        
        if(b_open2.isVisible()){
            
            //Salva o progresso da metodologia
            
            saveProgress();

            fileChooser2.setDialogTitle("Salvar [Arquivo de Progresso]");

            fileProgress.setProgress(progress);

            int returnVal2 = fileChooser2.showSaveDialog(this);
            if (returnVal2 == JFileChooser.APPROVE_OPTION) {
                File file2 = fileChooser2.getSelectedFile();
                String caminho2 = file2.getAbsolutePath();

                if (caminho2.endsWith(".pgr")){
                    object_progress.serializar(fileProgress, caminho2); 
                } else {
                    object_progress.serializar(fileProgress, caminho2.concat(".pgr"));       
                }

                System.out.println("** Arquivo de Progresso salvo com sucesso! **");
                JOptionPane.showMessageDialog(null, "Arquivo de execução/progresso salvo com sucesso!", "Aviso", JOptionPane.INFORMATION_MESSAGE);
            }
        } else {
            JOptionPane.showMessageDialog(null, "Nenhuma Metodologia Iniciada!");        
        }
        
    }
    
    /**
     * Processa os nós da aresta, um por chamada do metodo. Recebendo o id do TestNode.
     * @param id:id do node.
     * @return 
     */
    private TestNode processTestNode(int id){
        
        TestNode testNode = null;
        
        for(Iterator i = listVertexTests.iterator(); i.hasNext();){
            TestNode teste = (TestNode)i.next();
            
            if(teste.getId() == id){
                testNode = teste;
            }
        }
        return testNode;
        
    }
    
    /**
     * Processa o grafo da tela de conjuntos de tarefas
     * @param teste: recebe apenas o "Teste'
     * @return 
     */
    private DirectedSparseGraph<ToDoNode, String> processToDoNode(Teste teste){
        
        g2 = new DirectedSparseGraph<>();
        
        ToDoNode conj_etapa;
        for(Iterator i = teste.getListaDoConjuntoDasEtapas().iterator(); i.hasNext();){
            ConjuntoDeEtapas et = (ConjuntoDeEtapas)i.next();

            conj_etapa = new ToDoNode(et.getId(), et.getType(), et.getCatid());

            conj_etapa.setX(et.getX());
            conj_etapa.setY(et.getY());
            //conj_etapa.setNome(conj_etapa.getToDo().getName()); //Não tem nome no conj etapas, por enquanto.
            conj_etapa.getToDo().setName(teste.getTitulo());
            conj_etapa.getToDo().setListaDeEtapas(et.getListaDeEtapa());

            g2.addVertex(conj_etapa);
            nVertex2++;
        }

        Aresta aresta;
        for(Iterator i = teste.getListaDasArestasDasEtapas().iterator(); i.hasNext();){
            aresta = (Aresta) i.next();
            ToDoNode origem = null, destino = null;
            for(Iterator it = g2.getVertices().iterator(); it.hasNext();){
                ToDoNode toDo = (ToDoNode)it.next();
                if(aresta.getIdOrigem() == toDo.getId()) {
                    origem = toDo;
                }
                if(aresta.getIdDestino() == toDo.getId()) {
                    destino = toDo;
                }
            }
            g2.addEdge(aresta.getEdge(), origem, destino);
            nEdges2++;
        }
            
        return g2;
    }
    
    
    
    /**
     * Salva o progresso da metodologia
     */
    private void saveProgress() {
        
        this.progress = null;
        this.progress = new ArrayList<>();
        
        ArrayList<Progress> progress2 = new ArrayList<>();
        
        for(Iterator i = g1.getVertices().iterator(); i.hasNext();){
            TestNode t = (TestNode)i.next();
            
            for(Iterator j = t.getG().getVertices().iterator(); j.hasNext();){
                ToDoNode e = (ToDoNode)j.next();
                
                if((t.getType() == 2) && (e.getType() == 2)){
                    boolean[] c = e.getToDo().getListaDeCheckBox();
                    
                    Progress aux = new Progress(t.getId(), e.getId(), c);
                    
                    aux.setTableItens(e.getToDo().getTableItens());
                    aux.setTitleTable(e.getToDo().getTitleTable());
                    aux.setObservation(e.getToDo().getObservation());
                    aux.setActive(e.getToDo().getActive());
                    
                    progress2.add(aux);
                }
            }
        }
        
        this.progress = progress2;
        this.dadosMetodologia.setProgress(progress2);
        this.fileProgress.setProgress(progress2);
        this.fileProgress.setTextMetodology(dataMD5);

    }
    
    /**
     * Método carrega os dados do arquivo de progresso
     */
    private void loadProgress() {
        
        DirectedSparseGraph<ToDoNode, String> g_filho;
        
        //Atribuição do progresso
        progress = dadosMetodologia.getProgress();
        
        if (progress != null){
        
            //Percorre o array de progress
            for(Iterator i = progress.iterator(); i.hasNext();){
                Progress aux = (Progress)i.next();

                //Procura o Test/JFMStep referente a "aux"
                for (Iterator it = g1.getEdges().iterator(); it.hasNext();) {
                    String edge = (String) it.next();

                    //Percorre as arestas do teste
                    if(g1.getEndpoints(edge).getSecond().getId() == aux.getTestId()) {
                        
                        g_filho = g1.getEndpoints(edge).getSecond().getG();
                        
                        //Procura o Step/JFPStep referente a "aux"
                        for (Iterator jt = g_filho.getEdges().iterator(); jt.hasNext();) {
                            String edge2 = (String) jt.next();
                            
                            //Percorre as arestas do step
                            if(g_filho.getEndpoints(edge2).getSecond().getId() == aux.getStepId()){
                                
                                //Achou -> atribui o conjunto de checkboxs
                                g_filho.getEndpoints(edge2).getSecond().getToDo().setCheckBox(aux.getCheckBox());
                                
                                //Achou -> atribui as tabelas
                                g_filho.getEndpoints(edge2).getSecond().getToDo().setActive(aux.getActive());
                                g_filho.getEndpoints(edge2).getSecond().getToDo().setTitleTable(aux.getTitleTable());
                                g_filho.getEndpoints(edge2).getSecond().getToDo().setTableItens(aux.getTableItens());
                                g_filho.getEndpoints(edge2).getSecond().getToDo().setObservation(aux.getObservation());
                                
                            }
                        
                        }
                    }
                }  
            }
        
        } else {
        
            System.out.println("O progresso está vazio");
            JOptionPane.showMessageDialog(null, "O arquivo de execução/progresso está vazio!", "Aviso", JOptionPane.INFORMATION_MESSAGE);
            
        }
        
    }
    
    /**
     * Método inseri os dados do grafo em "dadosMetodologia"
     */
    private void loadData(){
        
        DirectedSparseGraph<TestNode, String> gTeste;
        TestNode object;
        
        if(g1.getVertices().isEmpty()){
            gTeste = g;
        }else{
            gTeste = g1;
        }
        
        // Atualizar a posição de cada vértice
        for (Iterator it = gTeste.getVertices().iterator(); it.hasNext();) {
            object = (TestNode) it.next();
            object.setX(layout.getX(object));
            object.setY(layout.getY(object));
        }
        
        boolean cont1 = true;
        
        ArrayList<Teste> listaDeTestes = new ArrayList<>();
        ArrayList<ConjuntoDeEtapas> listaConjuntoDeEtapas;
        
        // Percorre todos os vértices de testes
        for(Iterator itt = gTeste.getVertices().iterator(); itt.hasNext();){
            TestNode verticeTeste = (TestNode)itt.next();
            if(cont1){
                loadListEdgeTest();
                cont1 = false;
            }
            listaConjuntoDeEtapas = new ArrayList<>()
                    ;
            // Percorre todos os vertices das etapas
            for(Iterator itt2 = verticeTeste.getToDoScreen().getG().getVertices().iterator(); itt2.hasNext();){
                ToDoNode verticeEtapa = (ToDoNode) itt2.next();

                ConjuntoDeEtapas conjuntoDeEtapas = new ConjuntoDeEtapas();
                conjuntoDeEtapas.setId(verticeEtapa.getId());
                conjuntoDeEtapas.setType(verticeEtapa.getType());
                conjuntoDeEtapas.setCatid(verticeEtapa.getCatid());
                conjuntoDeEtapas.setX(verticeEtapa.getX());
                conjuntoDeEtapas.setY(verticeEtapa.getY());
                conjuntoDeEtapas.setListaDeEtapa(verticeEtapa.getToDo().getListaDeEtapas());
                listaConjuntoDeEtapas.add(conjuntoDeEtapas);
            }

            Teste teste = new Teste();
            teste.setTitulo(verticeTeste.getJFData().getNome());
            teste.setDescricaoTeste(verticeTeste.getJFData().getDescricao());
            teste.setId(verticeTeste.getId());
            teste.setType(verticeTeste.getType());
            teste.setCatid(verticeTeste.getCatid());
            teste.setX(verticeTeste.getX());
            teste.setY(verticeTeste.getY());

            teste.setListaDoConjuntoDasEtapas(listaConjuntoDeEtapas);
            teste.setListaDasArestasDasEtapas(loadListEdgeStep(verticeTeste.getToDoScreen().getG()));
            listaDeTestes.add(teste);
        }
        
        dadosMetodologia.setListaDeTestes(listaDeTestes);
        dadosMetodologia.setListaDasArestasDosTestes(listEdgeTest);
        
        //Carrega o progresso
        loadProgress();
        
    }
    
    /**
     * Método carrega a lista de arestas dos testes.
     */
    private void loadListEdgeTest(){
        
        DirectedSparseGraph<TestNode, String> gTeste;
        Object object;
        
        if(g1.getVertices().isEmpty()){
            gTeste = g;
        } else{
            gTeste = g1;
        }
        
        for(Iterator itt = gTeste.getEdges().iterator(); itt.hasNext();){
            object = itt.next();
            
            String edge_teste = (String)object;
            
            TestNode origem = gTeste.getSource(edge_teste);
            TestNode destino = gTeste.getDest(edge_teste);
            
            listEdgeTest.add(new Aresta(edge_teste, origem.getId(), destino.getId()));
        }
        
    }
    
    /**
     * Método carrega a lista de arestas das etapas.
     */
    private ArrayList<Aresta> loadListEdgeStep(DirectedSparseGraph<ToDoNode, String> g1) {
        
        ArrayList<Aresta> lista = new ArrayList<>();
        Object object;
        
        for(Iterator itt = g1.getEdges().iterator(); itt.hasNext();){
            object = itt.next();
            
            String edge_etapa = (String)object;
            
            ToDoNode origem = g1.getSource(edge_etapa);
            ToDoNode destino = g1.getDest(edge_etapa);
            
            lista.add(new Aresta(edge_etapa, origem.getId(), destino.getId()));
            System.out.print(edge_etapa + "[" + origem.getId() + "," + destino.getId() + "], ");
        }
        return lista;
        
    }
    
    /**
     * Método que verifica se os adjacentes que chegam estão concluídos.
     */
    private boolean neighborsFinished(DirectedSparseGraph<TestNode, String> g, String nome){ // verifica se todos os nos ao redor do catId(nome) sao verdes(state = 3)
        int aux = 0; //Variável diferente de zero representa que tem nó com estado não terminado.

        //Realiza a busca do nó pelo seu catId e armazena na variável 'node'.
        for (Iterator it = g.getEdges().iterator(); it.hasNext();) {
            String edge = (String) it.next();
            if (g.getEndpoints(edge).getSecond().getJFData().getNome().equals(nome)){
                if ((g.getEndpoints(edge).getFirst().getState() != 3) && (g.getEndpoints(edge).getFirst().getType() == 2)){
                    aux++;
                }
            }
        }

        //Teste final
        if (aux==0){
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * Método que define o estado do nó.
     */
    private void defineState(DirectedSparseGraph<TestNode, String> g, String nome){ // retorna a string referente a cor de cada no
        
        for (Iterator it = g.getEdges().iterator(); it.hasNext();) { // passa por todas as arestas
            String edge = (String) it.next();
            
            if (g.getEndpoints(edge).getSecond().getJFData().getNome().equals(nome)) { // seleciona as arestas q chegao ao catId
                
                if (g.getEndpoints(edge).getSecond().getToDoScreen().allFinished() && neighborsFinished(g,nome)) {// se todos os nos internos de catId forem verdes
                    g.getEndpoints(edge).getSecond().setState(3); // seta o state como 3(Verde)
                } else if (neighborsFinished(g,nome)) { // se os vertices que chegao no catId forem verdes ou se vinher do Start
                    g.getEndpoints(edge).getSecond().setState(1); // seta o state como 1(azul)
                } else /*if (!g.getEndpoints(edge).getSecond().getTodoscreen().allFinished() && !allFinished(g,catId))*/ { //se os nos internos nao forem todos verdes e todos os nos ao redor de catId nao forem verdes
                    g.getEndpoints(edge).getSecond().setState(2); // seta o state como 2(Vermelho)
                    
                    g.getEndpoints(edge).getSecond().getToDoScreen().dispose();
                    g.getEndpoints(edge).getSecond().getToDoScreen().disposeAll();
                }
            }
        }
    }
    
    /**
     * Método que, através do estado, define o icone do nó.
     */
    private String readIcon(DirectedSparseGraph<TestNode, String> g, String nome){
        String aux1 = ("/ImageFiles/" + "TestNode.png"); //Só para test_aux

        for (Iterator it = g.getEdges().iterator(); it.hasNext();) { // percorre todas as arestas
            String edge = (String) it.next();
            
            if ((g.getEndpoints(edge).getSecond().getJFData().getNome().equals(nome))&&(g.getEndpoints(edge).getSecond().getType() == 2)) {
                if (g.getEndpoints(edge).getSecond().getState() == 1) { // se state = 1
                    aux1 = ("/ImageFiles/" + "targetBall.png");// no azul
                } else if (g.getEndpoints(edge).getSecond().getState() == 2){ // se state = 2
                    aux1 = ("/ImageFiles/" + "TestNode.png"); // no vermelho
                } else if (g.getEndpoints(edge).getSecond().getState() == 3){ // se state = 3
                    aux1 = ("/ImageFiles/" + "TrueBall.png"); // no verde
                } else {
                    aux1 = ("/ImageFiles/" + "TestNode.png"); //Só para test_aux
                }
            } 
        }
        return (aux1);
    }
 
    /**
     * Método que, retorna uma lista de vetores, onde cada vetor possui um campos para: 
     * [0]nº do teste, [1]nº da conj_etapa, [2]% concluida, [3]quantidade de check box marcado, [4]qnt maxima de checkbox cada conj_etapa; 
     */
    private ArrayList<String[]> relatorioSimples() {
        int catid = 1;
        int catid2;

        ArrayList<String[]> dados = new ArrayList<>();

        while (catid <= nTests) {
            catid2 = 0;
            //Percorre todas as arestas
            for (Iterator it = g1.getEdges().iterator(); it.hasNext();) {
                String edge = (String) it.next();

                if (g1.getEndpoints(edge).getSecond().getCatid() == catid && g1.getEndpoints(edge).getSecond().getType() == 2){

                    while (catid2 <=  g1.getEndpoints(edge).getSecond().getToDoScreen().getNTests()) {
                        String[] conteudo = new String[5];
                        conteudo[0] = Integer.toString(catid);
                        dados.add(g1.getEndpoints(edge).getSecond().getToDoScreen().relatorioSimples(conteudo,catid2));
                        catid2++;
                    }
                }
            }
            catid++;
        }
        return dados;
    }
    
    /**
     * Método que, retorna uma lista de vetores, onde cada vetor possui um campos para: 
     * [0]nº do teste, [1]nº da conj_etapa, [2]String com Checkbox marcado(Ex 11100), [3]nome do teste, [4]descrição do teste, [6]a observação e [7]Id do test;
     */
    private ArrayList<String[]> relatorioSimples2() {
        int catid = 1;
        int catid2;

        ArrayList<String[]> dados = new ArrayList<>();

        while (catid <= nTests) {
            catid2 = 1;
            for (Iterator it = g1.getVertices().iterator(); it.hasNext();) { // percorre todos os vertices
                TestNode t = (TestNode) it.next();

                if (t.getCatid() == catid && t.getType() == 2){

                    while (catid2 <=  t.getToDoScreen().getNTests()) {
                        String[] conteudo = new String[7];
                        conteudo[0] = Integer.toString(t.getCatid());
                        conteudo[3] = t.getJFData().getNome();
                        conteudo[4] = t.getJFData().getDescricao();
                        conteudo[5] = Integer.toString(t.getId());
                        dados.add(t.getToDoScreen().relatorioSimples2(conteudo,catid2));
                        catid2++;
                    }
                }
            }
            catid++;
        }
        return dados;
    }
    
    private ArrayList<Anexo> relatorioAnexo() {
        int nTeste = 1;
        int nConjEtapa;
        int nEtapa;
        int etapaControle2;
        ArrayList<Anexo> anexoDoRelatorio = new ArrayList<>();
        
        while (nTeste <= nTests) {
            nConjEtapa = 1;
            for (Iterator it = g1.getVertices().iterator(); it.hasNext();) { // percorre todos os vertices
                TestNode t = (TestNode) it.next();
                
                if (t.getCatid() == nTeste && t.getType() == 2){
                    
                    while (nConjEtapa <=  t.getToDoScreen().getNTests()) {
                        nEtapa = 1;
                        etapaControle2 = t.getToDoScreen().numeroDeEtapas(nTeste,nConjEtapa);
                        while (nEtapa <= etapaControle2) {
                            anexoDoRelatorio.add(t.getToDoScreen().relatorioAnexo(nTeste,t.getNome(),nConjEtapa,nEtapa));
                            nEtapa++;
                        }
                        nConjEtapa++;
                    }
                }
            }
            nTeste++;
        }
        
//        for (Iterator it = anexoDoRelatorio.iterator(); it.hasNext();) {
//            Anexo a = (Anexo) it.next();
//            
//            System.out.println("nTeste: " + a.getNTeste() + "; nomeTeste: " + a.getNomeTeste() + "; nConjEtapa: " + a.getNConjEtapa() + 
//                    "; nEtapa: " + a.getNEtapa() + "; nomeEtapa: " + a.getNomeEtapa() + "; Titulos: " + a.getTitulosTabela() + "; table: " + a.getTable() + ";");
//        }
        return anexoDoRelatorio;
    }
    
    
//    private void centralizeMethodology(){
//        double menorX = 0;
//        double menorY = 0;
//        double maiorX = 0;
//        double maiorY = 0;
//        double xMedioGrafo = 0;
//        double yMedioGrafo = 0;
//        double xMedioTela = 0;
//        double yMedioTela = 0;
//        double ganhoX = 0;
//        double ganhoY = 0;
//        
//        //passo 1: determinar quais sao os maiores e menores X e Y do grafo
//        for (Iterator it = g1.getVertices().iterator(); it.hasNext();) {
//            TestNode t = (TestNode) it.next();
//            
//            if (menorX > t.getX()) {
//                menorX = t.getX();
//            }
//            if (maiorX < t.getX()) {
//                maiorX = t.getX();
//            }
//            
//            if (menorY > t.getY()) {
//                menorY = t.getY();
//            }
//            if (maiorY < t.getY()) {
//                maiorY = t.getY();
//            }
//        }
//        
//        //passo 2: Calcular o centro do grafo
//        if (maiorX > 0 && menorX < 0) {
//            xMedioGrafo = maiorX - ((menorX*(-1) + maiorX)/2);
//        } else if(maiorX < 0 && menorX > 0) {
//            xMedioGrafo = menorX + ((menorX + maiorX*(-1))/2);
//        } else {
//            xMedioGrafo = (maiorX + menorX) / 2;
//        }
//        
//        if (maiorY > 0 && menorY < 0) {
//            yMedioGrafo = maiorY - ((menorY*(-1) + maiorY)/2);
//        } else if(maiorY < 0 && menorY > 0) {
//            yMedioGrafo = menorY + ((menorY + maiorY*(-1))/2);
//        } else {
//            yMedioGrafo = (maiorY + menorY) / 2;
//        }
//        
//        //passo 3: Calcular o centro da tela
//        xMedioTela = vv.getX()/2;
//        yMedioTela = vv.getY()/2;
//        
//        //passo 4: Calcula o ganho que o grafo todo ira receber para ficar centralizado
//        ganhoX = xMedioTela - xMedioGrafo;
//        ganhoY = yMedioTela - yMedioGrafo;
//        
//        //passo 5: aplica o ganho X e Y a cada no do grafo
//        for (Iterator it = g1.getVertices().iterator(); it.hasNext();) {
//            TestNode t = (TestNode) it.next();
//            
//            t.setX(t.getX() + ganhoX);
//            t.setY(t.getY() + ganhoY);
//        }
//        reloadGraphScreen();
//    }
}
